package apibasej.basic.misc.standalone;

import java.sql.Timestamp;
import java.text.Normalizer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;

import apibasej.basic.config.ConfigManager;

public class UtilString {

	public static void main(String[] args) {
		
		//System.out.println(">>>"+toJavaConstantPattern("NomeDaClasse"));
		//System.out.println(">>>"+toJavaConstantPattern("nomeDaVar"));
		
		System.out.println(getNextString("xxx=Client; COMPUTERNAME=AZUL; HOSTNAME=null;", "xxx=", 23, ';','\n'));
		
	}
	
	public static String completeLeft(String s, char c, int totalSize){
		if(s!=null){
			if(s.length()>=totalSize) return s;
		}else{
			s = "";
		}
		StringBuilder sb = new StringBuilder(s);
		while(sb.length()<totalSize) {
			sb.insert(0,c);
		}
		return sb.toString();
	}
	public static String completeZerosLeft(String s, int totalSize){
		return completeLeft(s, '0', totalSize);
	}
	public static String completeSpacesLeft(String s, int totalSize){
		return completeLeft(s, ' ', totalSize);
	}
	public static String completeSpacesRight(String s, int totalSize){
		if(s!=null){
			if(s.length()>=totalSize) return s;
		}else{
			s = "";
		}
		StringBuilder sb = new StringBuilder(s);
		while(sb.length()<totalSize) sb.append(' ');
		return sb.toString();
	}

	
	public static String toJavaPattern(String str, boolean isEnt, boolean isPlural){
		StringBuilder sb = new StringBuilder(str.toLowerCase());
		if(isEnt) sb.setCharAt(0,Character.toUpperCase(sb.charAt(0)));
		for(int i=1;i<sb.length();i++){
			char atual = sb.charAt(i);
			if(atual=='_') {
				sb.setCharAt(i+1,Character.toUpperCase(sb.charAt(i+1)));
				sb.deleteCharAt(i);
			}
		}
		if(isPlural) sb.append('s');
		return sb.toString();
	}
	public static String toJavaConstantPattern(String str){
		StringBuilder sb = new StringBuilder(str);
		for(int i=0;i<sb.length(); i++){
			if(i>0 && Character.isUpperCase(sb.charAt(i)) && !Character.isUpperCase(sb.charAt(i-1))){
				sb.insert(i, '_');
				i++;
			}
		}
		return sb.toString().toUpperCase();
	}
	
	public static String genRegexEndsWith(String strEnd, boolean ignoreCase){
		StringBuilder r = new StringBuilder();
		if(ignoreCase) r.append("(?i)");
		r.append(".*");
		r.append(strEnd);
		r.append("$");
		return r.toString();
	}
	
	public static String genRegex(ArrayList<String> patternsIgnore, ArrayList<String> patternsInclude, boolean ignoreCase){
		StringBuilder r = new StringBuilder();
		if(patternsIgnore!=null && patternsIgnore.size()>0){
			r.append("(?!");
			if(ignoreCase) r.append("(?i)");
			boolean appendOr = false;
			for(String p : patternsIgnore){
				if(appendOr) r.append('|');
				r.append(p);
				appendOr = true;
			}
			r.append(')');
		}
		if(patternsInclude==null || patternsInclude.size()==0){
			r.append(".*");
		}else{
			r.append('(');
			if(ignoreCase) r.append("(?i)");
			boolean appendOr = false;
			for(String p : patternsInclude){
				if(appendOr) r.append('|');
				r.append(p);
				appendOr = true;
			}
			r.append(')');
		}
		return r.toString();
		
	}
	
	public static String onlyDigits(String s){
		if(s==null){
			return null;
		}
		StringBuilder resp = new StringBuilder("");
		for(char c : s.toCharArray()){
			if(Character.isDigit(c)){
				resp.append(c);
			}
		}
		return resp.toString();
	}
	public static String onlyLetters(String s, boolean addSpace){
		if(s==null){
			return null;
		}
		StringBuilder resp = new StringBuilder("");
		for(char c : s.toCharArray()){
			if(Character.isLetter(c) || (addSpace && c==' ')){
				resp.append(c);
			}
		}
		return resp.toString();
	}
	
	public static boolean isOnlyDigits(String s){
		if(s==null || s.length()==0){
			return false;
		}
		return onlyDigits(s).length()==s.length();
	}
	
	
	public static String toAscii(String s, boolean returnOriginalStringIfError){
		try{
			if(s==null){
				return null;
			}else{
				//http://docs.oracle.com/javase/tutorial/i18n/text/normalizerapi.html
				//http://www.guj.com.br/java/48001-comparar-strings-com-e-sem-acento/2
				return Normalizer.normalize(s, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "");
			}
		}catch(Throwable e){// somente por segurança, provavelmente nunca dará erro?
			ConfigManager.logDefAll(Level.SEVERE, "Erro ao converter String para ASCII: \""+s+"\"", e);
			if(returnOriginalStringIfError){
				return s;
			}else{
				throw e;
			}
		}
	}
	
	public static ArrayList<String> splitBySize(String s, int size){
		if(s==null){
			return null;
		}
		ArrayList<String> r = new ArrayList<>();
		for(int pos = 0; pos<s.length(); pos+=size){
			int end = pos+size;
			if(end>s.length()){
				end = s.length();
			}
			r.add(s.substring(pos,end));
		}
		return r;
	}
	
	public static int countChar(String s, char c){
		int ct = 0;
		for(char c1 : s.toCharArray()){
			if(c1==c){
				ct++;
			}
		}
		return ct;
	}
	
	public static boolean isAllCharsEquals(String s){
		if(s==null || s.length()==0){
			return false;
		}
		char c1 = s.charAt(0);
		for(char c2 : s.toCharArray()){
			if(c2!=c1){
				return false;
			}
		}
		return true;
	}
	
	
	
	//para retornar a data ele deve estar exatamente apos a strIdentIniValue, sem espaços e no formato exato do pattern
	public static Date getNextDate(String text, String strIdentIniValue, String patternDate){
		if(text==null){
			return null;
		}
		int pos = text.indexOf(strIdentIniValue);
		if(pos<0){
			return null;
		}
		int posIniRead = pos+strIdentIniValue.length();
		int posMaxRead = posIniRead+patternDate.length();
		if(posMaxRead>text.length()){
			return null;//significa que na frente do param não tem a data completa
		}
		String strDt = text.substring(posIniRead, posMaxRead);
		try{
			return new SimpleDateFormat(patternDate).parse(strDt);
		}catch(Throwable t){
			//System.out.println(">>>"+t);
			//log??? melhor não, pois se der erro significa que a data na frente da string não é valida
			return null;
		}
	}
	
	public static Timestamp getNextTimestamp(String text, String strIdentIniValue, String patternDate){
		Date dt = getNextDate(text, strIdentIniValue, patternDate);
		return dt==null?null:new Timestamp(dt.getTime());
	}
	
	public static Integer getNextInt(String text, String strIdentIniValue){
		Long l = getNextLong(text, strIdentIniValue);
		return l==null?null:l.intValue();
	}
	
	//para retornar o numero ele deve estar exatamente apos a strIdentIniValue, sem espaços
	public static Long getNextLong(String text, String strIdentIniValue){
		if(text==null){
			return null;
		}
		int pos = text.indexOf(strIdentIniValue);
		if(pos<0){
			return null;
		}
		int posIniRead = pos+strIdentIniValue.length();
		int posMaxRead = posIniRead+((""+Long.MAX_VALUE).length());
		if(posMaxRead>text.length()){
			posMaxRead = text.length();
		}
		StringBuilder sbNum = new StringBuilder();
		for(int i=posIniRead; i<posMaxRead; i++){
			char ch = text.charAt(i);
			if(Character.isDigit(ch)){
				sbNum.append(ch);
			}else{
				break;
			}
		}
		if(sbNum.length()>0){
			return Long.parseLong(sbNum.toString());
		}else{
			return null;
		}
	}
	
	//para retornar a string deve estar exatamente apos a strIdentIniValue, sem espaços
	public static String getNextString(String text, String strIdentIniValue, int maxStrLen, char... charsIdentEndStr){
		if(text==null){
			return null;
		}
		int pos = text.indexOf(strIdentIniValue);
		if(pos<0){
			return null;
		}
		int posIniRead = pos+strIdentIniValue.length();
		int posMaxRead = posIniRead+maxStrLen;
		if(posMaxRead>text.length()){
			posMaxRead = text.length();
		}
		if(charsIdentEndStr==null || charsIdentEndStr.length==0){
			charsIdentEndStr = new char[]{';','\n'};
		}
		StringBuilder sb = new StringBuilder();
		f1: for(int i=posIniRead; i<posMaxRead; i++){
			char ch = text.charAt(i);
			for(char end : charsIdentEndStr){
				if(end==ch){
					break f1;
				}
			}
			sb.append(ch);
		}
		if(sb.length()>0){
			return sb.toString();
		}else{
			return null;
		}
	}
	

	
}
